#include "../header/flickr.h"
#include <QtDebug>
#include <QDomNode>
#include <QDomText>
#include <QCryptographicHash>
#include <iostream>

Flickr::Flickr()
{
	api_key       = "12230fccf7fd30e778b85a58cc704286";
	shared_secret = "80eb916bbe0da4f6";
	flickr_host = "api.flickr.com";
	flickr_rest_path = "/services/rest/";
	flickr_auth_path = "/services/auth/";
	
	qhttp = new QHttp;
	
	connect(qhttp, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)), this, SLOT(readResponseHeader(const QHttpResponseHeader &)));

}

Flickr::~Flickr()
{
	delete qhttp;
}

void Flickr::GetFrob(const QString &user, const QString &pass)
{
	connect(qhttp, SIGNAL(requestFinished(int, bool)), this, SLOT(slGotFrob(int, bool)));
	qhttp->setHost(flickr_host);
	
	QMap<QString, QString> map;
	map["api_key"] = api_key;
	map["method"] = "flickr.auth.getFrob";
	
	QString api_sig = String2Md5( BuildSignature(shared_secret, map) );
	
	
	
	Frob.open(QBuffer::ReadWrite);
	Frob.seek(0);	
	httpGetFrobId = qhttp->get(flickr_rest_path+"?method=" + map["method"] +"&api_key="+map["api_key"]+"&api_sig="+api_sig, &Frob);
	
	qDebug() << "Getting...Frob!";
		
	return;
}

void Flickr::slGotFrob( int requestId, bool error )
{	
	if( httpGetFrobId != requestId )
		return;
		
	qDebug() << "got it (Frob!)\n";
	
	if(error)
	{
		qDebug() << "Error:";
		qDebug() << qhttp->errorString();
		return;
	}
	
	Frob.seek(0);
	int res = ParseFrob(Frob, frob);
	if(res)//error
	{
		qDebug() << "Ohh shit, err: " << frob;
		return;
	}

	qDebug() << "Good. " << frob;
	
	GetLogin();
	GetToken( Frob );
	return;
}


void Flickr::GetToken(QBuffer& buffer)
{
	connect(qhttp, SIGNAL(requestFinished(int, bool)), this, SLOT(slGotToken(int, bool)));

	QMap<QString, QString> map;

	map["api_key"] = api_key;
	map["frob"] = frob;
	map["method"] = "flickr.auth.getToken";
	
	QString api_sig( String2Md5( BuildSignature( shared_secret, map) ) );

	qhttp->setHost(flickr_host);
	buffer.close();
	buffer.setData("");
	qDebug() << flickr_rest_path + "?method=" + map["method"] + "&api_key=" + map["api_key"] + "&frob=" + map["frob"] + "&api_sig=" + api_sig;

	httpGetTokenId = qhttp->get(flickr_rest_path + "?method=" + map["method"] + "&api_key=" + map["api_key"] + "&frob=" + map["frob"] + "&api_sig=" + api_sig, &buffer);

	qDebug() << "Gettin Token";
}

void Flickr::slGotToken(int requestId, bool error)
{	
	//qDebug() << "CHECKED Token data: \n" << Frob.data();

	if( httpGetTokenId != requestId )
		return;
		
	qDebug() << "got it(Token)\n";

	if(error)
	{
		qDebug() << "Error:";
		qDebug() << qhttp->errorString();
		return;
	}
	
	qDebug() << "Token data:" << Frob.data();
}
	
void Flickr::GetLogin()
{
	int nr;

	QMap<QString, QString> map;
	map["api_key"] = api_key;
	map["perms"] = "delete";
	map["frob"] = frob;
	QString api_sig( String2Md5( BuildSignature( shared_secret, map) ) );
	
	qDebug() << flickr_host + "/services/auth/" + "?api_key=" + api_key + "&perms=" + map["perms"] + "&frob=" + map["frob"] + "&api_sig=" + api_sig;
	
	qDebug << "\n!!!After you followed the link, enter an integer to continue!!!\n";
	std::cin >> nr;
	qDebug() << nr;
}

void Flickr::readResponseHeader(const QHttpResponseHeader &responseHeader)
{
	CurrentResponseHeader = responseHeader;
	qDebug() << "Header received: " << CurrentResponseHeader.toString();
}


int Flickr::ParseFrob(QBuffer &frob, QString &strFrob)
{
	QDomDocument doc;
	QString errorStr;
	int errorLine;
	int errorColumn;
	int errcode=0;
	
	if ( !doc.setContent(&frob, true, &errorStr, &errorLine, &errorColumn) )
	{
		qDebug() << QObject::tr("Parse error at line %1, column %2:\n%3").arg(errorLine).arg(errorColumn).arg(errorStr);
		return 1;// ReturnVector;
	}

	QDomElement root = doc.documentElement();
	
	QString stat = root.attribute("stat");
	
	QDomNode node = root.firstChild();
	
	while (!node.isNull())
	{
		if (node.toElement().tagName() == "err")
		{
			errcode = node.toElement().attribute("code").toInt();
			strFrob = node.toElement().attribute("msg");
		}
		else if(node.toElement().tagName() == "frob")
		{
			if(node.firstChild().isText())
			{
				QDomText frob_dom = node.firstChild().toText();
				strFrob = frob_dom.data();
			}
		}
		node = node.nextSibling();
	}
	
	qDebug() << "stat = " << stat << ", errcode= " << errcode << ", frob= "<< strFrob;
	return errcode;
}

QString Flickr::String2Md5( const QString& RequestString)
{
	return QCryptographicHash::hash(RequestString.toUtf8(), QCryptographicHash::Md5).toHex();
}

QString Flickr::BuildSignature(const QString& secret, const QMap<QString, QString>& map)
{
	QString resData( secret );
	QMap<QString, QString>::const_iterator i = map.constBegin();
	while (i != map.constEnd())
	{
		resData += i.key() + i.value();
		i++;
	}
	
	qDebug() << resData;
	return resData;
}



